{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n",
        "什么是PyTorch?\n",
        "================\n",
        "\n",
        "PyTorch是一个基于python的科学计算包，主要针对两类人群：\n",
        "\n",
        "-   作为NumPy的替代品，可以利用GPU的性能进行计算\n",
        "-   作为一个高灵活性、速度快的深度学习平台\n",
        "\n",
        "入门\n",
        "---------------\n",
        "\n",
        "### 张量\n",
        "\n",
        "Tensor(张量）类似于NumPy的ndarray，但还可以在GPU上使用来加速计算。\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "from __future__ import print_function\nimport torch"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<div class=\"alert alert-info\"><h4>Note</h4><p>An uninitialized matrix is declared,\n    but does not contain definite known\n    values before it is used. When an\n    uninitialized matrix is created,\n    whatever values were in the allocated\n    memory at the time will appear as the initial values.</p></div>\n\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Construct a 5x3 matrix, uninitialized:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[5.9694e-39, 1.0010e-38, 1.0102e-38],\n        [1.0561e-38, 1.0469e-38, 1.0653e-38],\n        [1.0469e-38, 4.2246e-39, 1.0286e-38],\n        [1.0653e-38, 1.0194e-38, 8.4490e-39],\n        [1.0469e-38, 9.3674e-39, 9.9184e-39]])\n"
          ]
        }
      ],
      "source": [
        "x = torch.empty(5, 3)\nprint(x)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Construct a randomly initialized matrix:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[0.6555, 0.2010, 0.5330],\n        [0.8561, 0.0390, 0.9488],\n        [0.0261, 0.4982, 0.7917],\n        [0.9416, 0.2289, 0.9771],\n        [0.2752, 0.0869, 0.8989]])\n"
          ]
        }
      ],
      "source": [
        "x = torch.rand(5, 3)\nprint(x)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Construct a matrix filled zeros and of dtype long:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0],\n        [0, 0, 0]])\n"
          ]
        }
      ],
      "source": [
        "x = torch.zeros(5, 3, dtype=torch.long)\nprint(x)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Construct a tensor directly from data:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([5.5000, 3.0000])\n"
          ]
        }
      ],
      "source": [
        "x = torch.tensor([5.5, 3])\nprint(x)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "or create a tensor based on an existing tensor. These methods\nwill reuse properties of the input tensor, e.g. dtype, unless\nnew values are provided by user\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[1., 1., 1.],\n",
            "        [1., 1., 1.],\n",
            "        [1., 1., 1.],\n",
            "        [1., 1., 1.],\n",
            "        [1., 1., 1.]], dtype=torch.float64)\n",
            "tensor([[ 0.5288, -0.9197, -0.9625],\n",
            "        [-0.6804,  2.0704, -1.5042],\n",
            "        [ 1.8517,  1.0034, -0.5436],\n",
            "        [ 0.7162, -0.2793,  1.8727],\n",
            "        [ 1.1850, -0.9715,  0.2732]])\n"
          ]
        }
      ],
      "source": [
        "x = x.new_ones(5, 3, dtype=torch.double)      # new_* methods take in sizes\nprint(x)\n\nx = torch.randn_like(x, dtype=torch.float)    # override dtype!\nprint(x)                                      # result has the same size"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Get its size:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "torch.Size([5, 3])\n"
          ]
        }
      ],
      "source": [
        "print(x.size())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<div class=\"alert alert-info\"><h4>Note</h4><p>``torch.Size`` is in fact a tuple, so it supports all tuple operations.</p></div>\n\nOperations\n^^^^^^^^^^\nThere are multiple syntaxes for operations. In the following\nexample, we will take a look at the addition operation.\n\nAddition: syntax 1\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[ 1.5263, -0.1728, -0.0699],\n        [-0.1353,  2.1054, -0.5720],\n        [ 2.3765,  1.0567, -0.2747],\n        [ 0.8106,  0.2011,  2.3375],\n        [ 1.5897, -0.5988,  0.8384]])\n"
          ]
        }
      ],
      "source": [
        "y = torch.rand(5, 3)\nprint(x + y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Addition: syntax 2\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[ 1.5263, -0.1728, -0.0699],\n        [-0.1353,  2.1054, -0.5720],\n        [ 2.3765,  1.0567, -0.2747],\n        [ 0.8106,  0.2011,  2.3375],\n        [ 1.5897, -0.5988,  0.8384]])\n"
          ]
        }
      ],
      "source": [
        "print(torch.add(x, y))"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Addition: providing an output tensor as argument\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[ 1.5263, -0.1728, -0.0699],\n        [-0.1353,  2.1054, -0.5720],\n        [ 2.3765,  1.0567, -0.2747],\n        [ 0.8106,  0.2011,  2.3375],\n        [ 1.5897, -0.5988,  0.8384]])\n"
          ]
        }
      ],
      "source": [
        "result = torch.empty(5, 3)\ntorch.add(x, y, out=result)\nprint(result)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Addition: in-place\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 12,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([[ 1.5263, -0.1728, -0.0699],\n        [-0.1353,  2.1054, -0.5720],\n        [ 2.3765,  1.0567, -0.2747],\n        [ 0.8106,  0.2011,  2.3375],\n        [ 1.5897, -0.5988,  0.8384]])\n"
          ]
        }
      ],
      "source": [
        "# adds x to y\ny.add_(x)\nprint(y)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "<div class=\"alert alert-info\"><h4>Note</h4><p>Any operation that mutates a tensor in-place is post-fixed with an ``_``.\n    For example: ``x.copy_(y)``, ``x.t_()``, will change ``x``.</p></div>\n\nYou can use standard NumPy-like indexing with all bells and whistles!\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 13,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([-0.9197,  2.0704,  1.0034, -0.2793, -0.9715])\n"
          ]
        }
      ],
      "source": [
        "print(x[:, 1])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Resizing: If you want to resize/reshape tensor, you can use ``torch.view``:\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 14,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "torch.Size([4, 4]) torch.Size([16]) torch.Size([2, 8])\n"
          ]
        }
      ],
      "source": [
        "x = torch.randn(4, 4)\ny = x.view(16)\nz = x.view(-1, 8)  # the size -1 is inferred from other dimensions\nprint(x.size(), y.size(), z.size())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "If you have a one element tensor, use ``.item()`` to get the value as a\nPython number\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 15,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([-0.5743])\n-0.5742892026901245\n"
          ]
        }
      ],
      "source": [
        "x = torch.randn(1)\nprint(x)\nprint(x.item())"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "**Read later:**\n\n\n  100+ Tensor operations, including transposing, indexing, slicing,\n  mathematical operations, linear algebra, random numbers, etc.,\n  are described\n  `here <https://pytorch.org/docs/torch>`_.\n\nNumPy Bridge\n------------\n\nConverting a Torch Tensor to a NumPy array and vice versa is a breeze.\n\nThe Torch Tensor and NumPy array will share their underlying memory\nlocations (if the Torch Tensor is on CPU), and changing one will change\nthe other.\n\nConverting a Torch Tensor to a NumPy Array\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 16,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([1., 1., 1., 1., 1.])\n"
          ]
        }
      ],
      "source": [
        "a = torch.ones(5)\nprint(a)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 17,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[1. 1. 1. 1. 1.]\n"
          ]
        }
      ],
      "source": [
        "b = a.numpy()\nprint(b)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "See how the numpy array changed in value.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 18,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "tensor([2., 2., 2., 2., 2.])\n",
            "[2. 2. 2. 2. 2.]\n"
          ]
        }
      ],
      "source": [
        "a.add_(1)\nprint(a)\nprint(b)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Converting NumPy Array to Torch Tensor\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nSee how changing the np array changed the Torch Tensor automatically\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 19,
      "metadata": {
        "collapsed": false
      },
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "[2. 2. 2. 2. 2.]\n",
            "tensor([2., 2., 2., 2., 2.], dtype=torch.float64)\n"
          ]
        }
      ],
      "source": [
        "import numpy as np\na = np.ones(5)\nb = torch.from_numpy(a)\nnp.add(a, 1, out=a)\nprint(a)\nprint(b)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "All the Tensors on the CPU except a CharTensor support converting to\nNumPy and back.\n\nCUDA Tensors\n------------\n\nTensors can be moved onto any device using the ``.to`` method.\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 20,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# let us run this cell only if CUDA is available\n# We will use ``torch.device`` objects to move tensors in and out of GPU\nif torch.cuda.is_available():\n    device = torch.device(\"cuda\")          # a CUDA device object\n    y = torch.ones_like(x, device=device)  # directly create a tensor on GPU\n    x = x.to(device)                       # or just use strings ``.to(\"cuda\")``\n    z = x + y\n    print(z)\n    print(z.to(\"cpu\", torch.double))       # ``.to`` can also change dtype together!"
      ]
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.7.6-final"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}